package xdu.lz.stage6_threadpool.chapter3_threadPoolExecutorAPI.myFuture;

import java.util.concurrent.Callable;

public class FutureTask<T> implements Future<T>,Runnable {

    private volatile boolean done = false;

    private T result;

    private Callable<T> callable;

    public FutureTask(Callable<T> callable) {
        this.callable = callable;
    }

    private Runnable runnable;

    //注册完成触发回调任务
    public FutureTask(Callable<T> callable,Runnable runnable) {
        this.callable = callable;
        this.runnable = runnable;
    }

    @Override
    public void run() {
        try {
            result = callable.call();
            //调用传过来的方法回调
            if(this.runnable != null){
                new Thread(this.runnable).start();
            }
            this.done(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // get是main线程调用的
    public void done(T result) {
        synchronized (this) {
            this.result = result;
            this.done = true;
        }
    }

    @Override
    public T get() throws InterruptedException {
        synchronized (this) {
            //没有执行完成则一直阻塞
            while (!done) {
                //让调用方法的线程阻塞，等待获取结果
                this.wait();
            }
        }
        return result;
    }

    @Override
    public T tryGet(long mills) throws InterruptedException, TimeOutException {
        synchronized (this) {
            while (!done) {
                this.wait(mills);
                if (!done) {
                    throw new TimeOutException("超时");
                }
            }
        }
        return result;
    }
}
